// 使用 D8 内置的 readbuffer 函数读取 Wasm 文件
const buffer = readbuffer("/home/sjk/桌面/asc_test/build/test1.wasm");

// 定义初始化和调用 WebAssembly 模块的函数
async function instantiateWasm(buffer) {
    const importObject = {
        env: {
            abort: function (message, fileName, lineNumber, columnNumber) {
                throw new Error(`${message} in ${fileName}:${lineNumber}:${columnNumber}`);
            }
        }
    };

    const module = await WebAssembly.compile(buffer);
    const instance = await WebAssembly.instantiate(module, importObject);

    const memory = instance.exports.mem;  // 从Wasm模块中导出的 WebAssembly.Memory 实例对象
    const dataview = new DataView(memory.buffer);
    // 获取最新的 DataView 对象
    function getDataView() {
        return new DataView(memory.buffer);
    }

    // 将数组转为 WebAssembly 线性内存格式
    function lowerArray(values) {
        const start = performance.now();
        const length = values.length;
        const pointer = instance.exports.__pin(instance.exports.__new(length << 2, 1));
        const dataview = getDataView();
        for (let i = 0; i < length; i++) {
            dataview.setInt32(pointer + (i << 2), values[i], true);
        }
        instance.exports.__unpin(pointer);
        const end = performance.now();
        return { pointer, time: end - start };
    }

    // 从 WebAssembly 线性内存中提取数组
    function liftArray(pointer, length) {
        const start = performance.now();
        const dataview = getDataView();
        const result = new Int32Array(dataview.buffer, pointer, length);
        const end = performance.now();
        return { result, time: end - start };
    }

    return {
        baselineTest: () => {
            instance.exports.baselineTest();
            return { lowerTime: 0, liftTime: 0 };
        },
        noInputWithOutput: () => {
            const resultPointer = instance.exports.noInputWithOutput();
            const { result, time: liftTime } = liftArray(resultPointer, 100000);
            return { result, lowerTime: 0, liftTime };
        },
        withInputAndOutput: (numbers) => {
            const { pointer, time: lowerTime } = lowerArray(numbers);
            const resultPointer = instance.exports.withInputAndOutput(pointer);
            const { result, time: liftTime } = liftArray(resultPointer, 100000);
            return { result, lowerTime, liftTime };
        },
        withInputNoOutput: (numbers) => {
            const { pointer, time: lowerTime } = lowerArray(numbers);
            instance.exports.withInputNoOutput(pointer);
            return { lowerTime, liftTime: 0 };
        }
    };
}

// 测试代码
async function test() {
    try {
        const wasmFunctions = await instantiateWasm(buffer);

        const inputArray = new Array(100000).fill(0).map((_, i) => i + 1);
        const iterations = 100;

        // 辅助函数：执行测试并记录时间
        function runTest(name, testFunction) {
            const start = performance.now();
            let totalLowerTime = 0;
            let totalLiftTime = 0;

            for (let i = 0; i < iterations; i++) {
                const result = testFunction();
                totalLowerTime += result.lowerTime;
                totalLiftTime += result.liftTime;
            }

            const end = performance.now();

            console.log(`${name}: ${end - start}ms`);
            if (totalLowerTime > 0) {
                console.log(`  LowerArray Time: ${totalLowerTime}ms`);
            }
            if (totalLiftTime > 0) {
                console.log(`  LiftArray Time: ${totalLiftTime}ms`);
            }
        }

        // Baseline Test
        // runTest('Baseline Test', wasmFunctions.baselineTest);

        // No Input, With Output
        // runTest('No Input, With Output', wasmFunctions.noInputWithOutput);

        // With Input, With Output
        runTest('With Input, With Output', () => wasmFunctions.withInputAndOutput(inputArray));

        // With Input, No Output
        // runTest('With Input, No Output', () => wasmFunctions.withInputNoOutput(inputArray));
    } catch (error) {
        console.error(`Error: ${error.message}`);
    }
}

// 运行测试
test().catch((err) => print(`Error: ${err}`));